<?php

namespace app\index\service;

use app\common\model\Consulting;
use app\common\model\ConsultingServer;
use app\common\model\Member;
use app\common\model\RankBroadcast;
use app\common\service\TemplateSmsService;
use app\index\dao\ConsultingDao;
use app\index\model\UM as UM;
use app\index\traits\MutedTrait;
use ShidianUtil\Utils\CheckUtil;
use ShidianUtil\Utils\TimeUtil;
use think\Collection;
use think\exception\ValidateException;

/**
 * Class ConsultingRushService
 * @package app\index\service
 */
class ConsultingRushService
{
    use MutedTrait;

    // dao
    private ConsultingDao $consultingDao;
    private BroadcastService $broadcastService;

    public function __construct(ConsultingDao $consultingDao, BroadcastService $broadcastService)
    {
        $this->consultingDao = $consultingDao;
        $this->broadcastService = $broadcastService;
    }

    /**
     * 列表V1
     * @param UM $user
     * @param int|null $page
     * @param int|null $page_size
     * @return Collection
     */
    public function index(UM $user, $categoryId, $cityId, ?int $page = null, ?int $page_size = null): Collection
    {
        $lawyerId = $user->id;

        return $this->consultingDao->selectCanRush($lawyerId, $categoryId, $cityId, $page, $page_size);
    }

    /**
     * 列表V2
     * @param UM $user
     * @param $listType
     * @param int|null $page
     * @param int|null $page_size
     * @return Collection
     */
    public function indexv2(UM $user, $listType, ?int $page = null, ?int $page_size = null): Collection
    {
        if ($user->type != 1 || is_null($user->memberInfo)) {
            return \think\model\Collection::make();
        }

        $rushStatus = [0, 2];
        if ($user->memberInfo->medal != 1) {
            $rushStatus = [2];
        }

        // 电话咨询的服务
        $phoneConsultingServerIds = ConsultingServer::where('serverType', ConsultingServer::PHONE)
                                                    ->field(['id'])
                                                    ->select()
                                                    ->column('id');

        $consultingServerIds = null;
        if ($listType == '1') {
            // 电话咨询
            $consultingServerIds = $phoneConsultingServerIds;
        } elseif ($listType == '2') {
            // 非电话咨询
            $consultingServerIds = ConsultingServer::where('serverType', '<>', ConsultingServer::PHONE)
                                                   ->field(['id'])
                                                   ->select()
                                                   ->column('id');
        }

        return $this->consultingDao
            ->selectRushV3($rushStatus, $consultingServerIds, $page, $page_size)
            ->each(function ($record) use ($phoneConsultingServerIds) {
                $record->listType = in_array($record->consultingServerId, $phoneConsultingServerIds) ? '1' : '2';

                $category = $record->category;
                if (!is_null($category) && not_blank($category->name)) {
                    $record->listName = $category->name;
                } else {
                    if ($record->listType == '1') {
                        $record->listName = '电话咨询';
                    } else {
                        $record->listName = '1V1咨询';
                    }
                }
            });
    }

    /**
     * 抢单+确认
     * @param UM $user
     * @param int $id
     * @param array $params
     * @return Consulting
     */
    public function rushAndConfirm(UM $user, int $id, array $params): Consulting
    {
        $userId = $user->id;
        $userName = $user->showName;

        if ($user->type != 1) {
            throw new ValidateException('律师才能抢单');
        }

        $this->checkMuted($user);

        // 咨询
        $record = Consulting::field(true)->where('id', $id)
                            ->whereIn('matchType', [Consulting::MATCH_TYPE_RUSH, Consulting::MATCH_TYPE_SVIP])
                            ->where('status', 1)
                            ->find();

        if (is_null($record)) {
            throw new ValidateException('下次在快一点，2分钟未接单，将同时推送您本省的竞争律师。');
        }

        if ($record->matchType == Consulting::MATCH_TYPE_SVIP) {
            if ($user->svip != 1) {
                throw new ValidateException('您不是SVIP不能提前抢单');
            }
        } else {
            if ($user->memberInfo->medal != 1) {
                throw new ValidateException('已被律师抢单。关注公众号接收付费推送。及时赚钱抢单。');
            }
        }

        if (is_id($record->lawyerId)) {
            if ($record->lawyerId == $userId) {
                $record->rushResult = '101';
                return $record;
            }

            if ($record->matchType == Consulting::MATCH_TYPE_SVIP) {
                throw new ValidateException('下次在快一点，2分钟未接单，将同时推送您本省的竞争律师。');
            } else {
                throw new ValidateException('已被律师抢单。关注公众号接收付费推送。及时赚钱抢单。');
            }
        }

        if ($record->rushStatus != 0) {
            throw new ValidateException('下次在快一点，2分钟未接单，将同时推送您本省的竞争律师。');
        }

        // 判断该律师是否已经匹配了该问题下的其他咨询
        if (is_id($record->questionId)) {
            $exists = Consulting::where('questionId', $record->questionId)
                                ->where('lawyerId', $userId)
                                ->field(['id'])
                                ->find();
            if ($exists) {
                throw new ValidateException('您已经匹配了该问题，请勿重复抢单');
            }
        }

        // 抢单匹配律师
        $success = $this->getConsultingLawyerMatchService()->matchRush($record, $userId);

        // 抢单结果
        $record->rushResult = $success ? '101' : '102';

        $memberId = $record->memberId;
        if (is_id($memberId)) {
            $phone = Member::where('id', $memberId)->value('phone');
            if (CheckUtil::isPhoneNumber($phone)) {
                $this->getTemplateSmsService()->rushRemind($phone);
            }
        }

        // 抢单成功， 记录实时播报
        if ($success) {
            $this->addBroadcast($userId, $userName);
        }

        return $record;
    }

    private function getConsultingLawyerMatchService(): ConsultingLawyerMatchService
    {
        return app(ConsultingLawyerMatchService::class);
    }

    private function getTemplateSmsService(): TemplateSmsService
    {
        return app(TemplateSmsService::class);
    }

    /**
     * 添加实时播报
     * @param int $userId
     * @param string $userName
     * @return void
     */
    private function addBroadcast(int $userId, string $userName): void
    {
        $total = Consulting::where('lawyerId', $userId)
                           ->whereIn('matchType', [Consulting::MATCH_TYPE_RUSH, Consulting::MATCH_TYPE_SVIP])
                           ->where('rushStatus', 2)
                           ->where('rushTime', '>=', TimeUtil::stamp(TimeUtil::DAY))
                           ->count();

        if ($total == 0) {
            $total = 1;
        }

        $message = [
            ['type' => 'text', 'red' => 102, 'text' => '抢单了付费咨询，今日抢单 '],
            ['type' => 'text', 'red' => 101, 'text' => $total],
            ['type' => 'text', 'red' => 102, 'text' => ' 次'],
        ];

        $this->broadcastService->addBroadcast(RankBroadcast::QIANGDAN, $userId, $userName, $message);
    }
}
